package tfc_editor.GUI;
import javax.swing.*;
import javax.swing.event.*;

import tfc_editor.pastrytools.PastryManager;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.*;


/**
 * Clase que gestiona tot la GUI i la interficie amb l'usuari per part de la finestra principal de l'editor.
 * @author Ismael Gonzalez Burgos
 *
 */
public class EditorGUI  implements ActionListener, DocumentListener, WindowListener
{
	private static final String Window_Title = "NotePeer";
	private static final String B_Nou_Text = "Nou";
	private static final String B_Carregar_Offline_Text = "Carregar Offline";
	private static final String B_Desar_Offline_Text = "Desar Offline";
	private static final String B_Carregar_Online_Usuari_Text = "Carregar Online (Directori usuari)";
	private static final String B_Desar_Online_Usuari_Text = "Desar Online (Directori usuari)";
	private static final String B_Carregar_Online_Shared_Text = "Carregar Online (Directori compartit)";
	private static final String B_Desar_Online_Shared_Text = "Desar Online (Directori compartit)";
	private static final String B_Veure_Directori_Usuari_Text = "Veure el directori online de l'usuari";
	private static final String B_Veure_Directori_Compartit_Text = "Veure el directori compartit";
	private static final String B_Sortir_Text = "Sortir";
	private static final String B_Login_Text = "Login";
	private static final String B_Crear_Usuari_Text = "Crear usuari";
	private static final String B_SelTot_Text = "Seleccionar tot";
	private static final String B_Tallar_Text = "Tallar";
	private static final String B_Copiar_Text = "Copiar";
	private static final String B_Enganxar_Text = "Enganxar";
	private static final String B_Sobre_Text = "Quant a...";
	
	private JMenu MenuOnline;

    private JTextArea output;
    private JScrollPane scrollPane;
    private JFrame frame;
    private boolean TextModified;
    private PastryManager pm;
    
    private String NomFitxer;

    /**
     * Funcio per guardar el nom del fitxer amb el que actualment estem treballant.
     * @param FileName Nom del fitxer.
     */
    void SetFileName(String FileName)
    {
    	NomFitxer = FileName;
    	UpdateHeader();
    }
    
    /**
     * Funcio per actualitzar la capcelera la finestra.
     */
    void UpdateHeader()
    {
    	String Title = "";
    	
    	if (NomFitxer.length() > 0)
    		Title += " - " + NomFitxer;

    	if (TextModified)
    		Title += " [Modificat]";

    		frame.setTitle(Window_Title + Title);
    }

    /**
     * Getter del frame contenidor.
     * @return El frame.
     */
    public JFrame GetFrame()
    {
    	return frame;
    }
    
    /**
     * Geter de l'area de text.
     * @return El JTextArea de la finestra.
     */
    public JTextArea GetTextArea()
    {
    	return output;
    }
    
    /**
     * Geter del PastryManager.
     * @return Punter al PastryManager.
     */
    public PastryManager GetPastryManager()
    {
    	return pm;
    }

	/**
	 * Crea el menu del programa.
	 * @return El menu creat.
	 */
    public JMenuBar createMenuBar()
    {
        JMenuBar menuBar;
        JMenu menu;
        JMenuItem menuItem;

        menuBar = new JMenuBar();

        menu = new JMenu("Arxiu");
        menu.setMnemonic(KeyEvent.VK_A);
        menuBar.add(menu);

        menuItem = new JMenuItem(B_Nou_Text,KeyEvent.VK_N);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Buidar el texte");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        menu.addSeparator();

        menuItem = new JMenuItem(B_Carregar_Offline_Text,KeyEvent.VK_C);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Carregar un fitxer On-line");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        menuItem = new JMenuItem(B_Desar_Offline_Text,KeyEvent.VK_D);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Desar el fitxer Off-line");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        menu.addSeparator();

        menuItem = new JMenuItem(B_Sortir_Text,KeyEvent.VK_S);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Sortir del programa");
        menuItem.addActionListener(this);
        menu.add(menuItem);
  
        // Segon menu, editar.
        menu = new JMenu("Editar");
        menu.setMnemonic(KeyEvent.VK_E);
        menu.getAccessibleContext().setAccessibleDescription("Opcions per editar el texte");
        menuBar.add(menu);

        menuItem = new JMenuItem(B_SelTot_Text,KeyEvent.VK_S);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Seleccionar tot el text");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        menuItem = new JMenuItem(B_Tallar_Text,KeyEvent.VK_T);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Tallar el text seleccionat");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        menuItem = new JMenuItem(B_Copiar_Text,KeyEvent.VK_C);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Copiar el text seleccionat");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        menuItem = new JMenuItem(B_Enganxar_Text,KeyEvent.VK_E);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Sortir del programa");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        // Menu, Online action.
        MenuOnline = new JMenu("Accions online");
        MenuOnline.getAccessibleContext().setAccessibleDescription("Accions dels fitxers online");
        menuBar.add(MenuOnline);

        menuItem = new JMenuItem(B_Carregar_Online_Usuari_Text,KeyEvent.VK_N);
        menuItem.getAccessibleContext().setAccessibleDescription("Carregar un fitxer Online al directori de l'usuari");
        menuItem.addActionListener(this);
        MenuOnline.add(menuItem);

        menuItem = new JMenuItem(B_Desar_Online_Usuari_Text,KeyEvent.VK_R);
        menuItem.getAccessibleContext().setAccessibleDescription("Desar el fitxer Online al directori de l'usuari");
        menuItem.addActionListener(this);
        MenuOnline.add(menuItem);

        MenuOnline.addSeparator();

        menuItem = new JMenuItem(B_Carregar_Online_Shared_Text,KeyEvent.VK_C);
        menuItem.getAccessibleContext().setAccessibleDescription("Carregar un fitxer Online al directori compartit");
        menuItem.addActionListener(this);
        MenuOnline.add(menuItem);

        menuItem = new JMenuItem(B_Desar_Online_Shared_Text,KeyEvent.VK_I);
        menuItem.getAccessibleContext().setAccessibleDescription("Desar el fitxer Online al directori compartit");
        menuItem.addActionListener(this);
        MenuOnline.add(menuItem);

        MenuOnline.addSeparator();

        menuItem = new JMenuItem(B_Veure_Directori_Usuari_Text,KeyEvent.VK_U);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Veure directori online de l'usuari");
        menuItem.addActionListener(this);
        MenuOnline.add(menuItem);

        menuItem = new JMenuItem(B_Veure_Directori_Compartit_Text,KeyEvent.VK_C);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Veure directori online compartit");
        menuItem.addActionListener(this);
        MenuOnline.add(menuItem);
        
        MenuOnline.setEnabled(false);

        // Menu usuaris.
        menu = new JMenu("Gestionar usuaris");
        menu.setMnemonic(KeyEvent.VK_U);
        menu.getAccessibleContext().setAccessibleDescription("Gestions d'usuaris");
        menuBar.add(menu);

        menuItem = new JMenuItem(B_Login_Text,KeyEvent.VK_G);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Realitzar un login d'usuari");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        menuItem = new JMenuItem(B_Crear_Usuari_Text,KeyEvent.VK_C);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Crear un nou usuari");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        // Menu ajuda.
        menu = new JMenu("Ajuda");
        menu.setMnemonic(KeyEvent.VK_J);
        menu.getAccessibleContext().setAccessibleDescription("Opcions d'ajuda");
        menuBar.add(menu);

        menuItem = new JMenuItem(B_Sobre_Text,KeyEvent.VK_S);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription("Seleccionar tot el text");
        menuItem.addActionListener(this);
        menu.add(menuItem);

        return menuBar;
    }

	/**
	 * Funció que activa els menus de gestionament online quan ja tenim l'usuari logejat.
	 */
    public void ActivateOnlineMenus()
    {
    	MenuOnline.setEnabled(true);
    }

	/**
	 * Funció per notificar que s'ha modificat el text de l'editor.
	 * @param ev Document modificat.
	 */
    public void insertUpdate(DocumentEvent ev)
    {
    	SetTextModified(true);
    }

	/**
	 * Funció per notificar que s'ha modificat el text de l'editor.
	 * @param ev Document modificat.
	 */
	public void changedUpdate(DocumentEvent ev)
	{
    	SetTextModified(true);
	}

	/**
	 * Funció per notificar que s'ha modificat el text de l'editor.
	 * @param ev Document modificat.
	 */
	public void removeUpdate(DocumentEvent ev)
	{
    	SetTextModified(true);
	}

	/**
	 * Funcio que inicialitza el contenidor on es crea l'area de text i el menu.
	 * @return El contenidor creat.
	 */
    public Container createContentPane()
    {
        //Create the content-pane-to-be.
        JPanel contentPane = new JPanel(new BorderLayout());
        contentPane.setOpaque(true);

        //Create a scrolled text area.
        output = new JTextArea(5, 30);
        output.setEditable(true);
        scrollPane = new JScrollPane(output);
        output.getDocument().addDocumentListener(this);

        //Add the text area to the content pane.
        contentPane.add(scrollPane, BorderLayout.CENTER);

        return contentPane;
    }

    /**
     * Funcio que executa l'accio quan es vol carregar un fitxer online.
     */
    public void CarregarOnLinePressed(boolean Shared)
    {
    	boolean DoWork = true;
    	if (GetTextModified())
    	{
    		int Result = new FileSaver(frame,output,pm,this).AskSave();
    		if (Result != FileSaver.SAVE_TOTBE && Result != FileSaver.SAVE_NO_VOLGUARDAR)
    		{
    			DoWork = false;
    		}
    	}

    	if (DoWork)
    		new FinestraGestioFitxerOnLine(pm,false,Shared,this).setVisible(true);
    }
    
    /**
     * Funcio que executa l'accio quan es vol desar un fitxer online.
     * @param Shared Si el fitxer el bolen carregar del directori compartit o no.
     */
    public void DesarOnLinePressed(boolean Shared)
    {
    	new FinestraGestioFitxerOnLine(pm,true,Shared,this).setVisible(true);
    }

    /**
	 * Funcio per gestionar els events dels elements de la GUI.
	 * @param e Event enviat pel sistema.
	 */
    public void actionPerformed(ActionEvent e)
    {
        JMenuItem source = (JMenuItem)(e.getSource());
        if (source.getText()==B_Nou_Text)
        {
        	if (GetTextModified())
        	{
        		int result = new FileSaver(frame,output,pm,this).AskSave();
        		if (result==FileSaver.SAVE_TOTBE || result==FileSaver.SAVE_NO_VOLGUARDAR)
        		{
        			output.setText("");
        			SetFileName("");
        			SetTextModified(false);
        		}
        	}
        }
        else if (source.getText()==B_Sortir_Text)
        {
        	System.exit(0);
        }
        else if (source.getText()==B_Carregar_Offline_Text)
        {
        	if (GetTextModified())
        		new FileSaver(frame,output,pm,this).AskSave();
        	new FileLoader(frame,output,pm,this).LoadFile();
        }
        else if (source.getText()==B_Desar_Offline_Text)
        {
    		int result =new FileSaver(frame,output,pm,this).SaveFile();
    		if (result==FileSaver.SAVE_TOTBE)
    			SetTextModified(false);
        }
        else if (source.getText()==B_Carregar_Online_Usuari_Text)
        {
        	CarregarOnLinePressed(false);
        }
        else if (source.getText()==B_Desar_Online_Usuari_Text)
        {
        	DesarOnLinePressed(false);
        }
        else if (source.getText()==B_Carregar_Online_Shared_Text)
        {
        	CarregarOnLinePressed(true);
        }
        else if (source.getText()==B_Desar_Online_Shared_Text)
        {
        	DesarOnLinePressed(true);
        }
        else if (source.getText()==B_Veure_Directori_Usuari_Text)
        {
        	new FinestraMostrarFitxers(pm,this,false).setVisible(true);
        }
        else if (source.getText()==B_Veure_Directori_Compartit_Text)
        {
        	new FinestraMostrarFitxers(pm,this,true).setVisible(true);
        }
        else if (source.getText()==B_SelTot_Text)
        {
        	output.selectAll();
        }
        else if (source.getText()==B_Copiar_Text)
        {
        	output.copy();
        }
        else if (source.getText()==B_Tallar_Text)
        {
        	output.cut();
        }
        else if (source.getText()==B_Enganxar_Text)
        {
        	output.paste();
        }
        else if (source.getText()==B_Login_Text)
        {
        	new FinestraLogIn(pm,this).setVisible(true);
        }
        else if (source.getText()==B_Crear_Usuari_Text)
        {
        	new FinestraCrearUsuari(pm,this).setVisible(true);
        }
        else if (source.getText()==B_Sobre_Text)
        {
        	JOptionPane.showMessageDialog(frame, "NotePeer\n" +
        			"Editor en xarxa KBR que utilitza freepastry/Bunshin" +
        			"Projecte final de carrera de l'alumne:\n" +
        			"Ismael Gonzalez Burgos\n" +
        			"Versió: 1.21.10   Compilat: 07/10/2010","Informacio del programa",JOptionPane.INFORMATION_MESSAGE);
        }
    }
    
    /**
     * Funcio que canvia l'estat del valor modified del text del editor i actualitza la barra del titol.
     * @param NewVal Si el text esta modificat o no.
     */
    public void SetTextModified(boolean NewVal)
    {
    	TextModified = NewVal;
    	UpdateHeader();
    }

	/**
	 * Funcio que retorna si el text ha estat modificat o no per l'usuari
	 * @return Si el text ha estat modificat o no.
	 */
    public boolean GetTextModified()
    {
    	return TextModified;
    }

	/**
	 * Constructor per a crear l'editor.
	 * @param PM Punter a la clases PastryManager.
	 */
    public EditorGUI(PastryManager PM)
    {
    	// Guardem el PastryManager.
    	pm = PM;
    	
    	NomFitxer = "";
        //Create and set up the window.
        frame = new JFrame(Window_Title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addWindowListener(this);

        // El texte no ha estat modificat.
        SetTextModified(false);

        frame.setContentPane(createContentPane());
        frame.setJMenuBar(createMenuBar());

        // Mostrem la finestra.
        frame.setSize(550, 260);
        frame.setVisible(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    }
    
    /**
     * Funcio que escolta els events de tancar finestra.
     * @param e Event rebut.
     */
	public void windowClosing(WindowEvent e)
	{
		if (GetTextModified())
			new FileSaver(frame,output,pm,this).AskSave();
	}

	/**
	 * Funcio que escolta els events de quan la finestra s'activa.
	 * @param e Event rebut. 
	 */
	public void windowActivated(WindowEvent e)
	{
	}

	/**
	 * Funcio que escolta els events de tancar finestra sense mes opcio.
	 * @param e Event rebut.
	 */
	public void windowClosed(WindowEvent e)
	{
		
	}

	/**
	 * Funcio que escolta els events de quan la finestra es desactiva.
	 * @param e Event rebut.
	 */
	public void windowDeactivated(WindowEvent e) 
	{
		
	}

	/**
	 * Funcio que escolta els events de quan la finestra es fa una icona.
	 * @param e Event rebut.
	 */
	public void windowDeiconified(WindowEvent e)
	{
		
	}

	/**
	 * Funcio que escolta els events de quan la finestra es ja una icona.
	 * @param e Event rebut.
	 */
	public void windowIconified(WindowEvent e)
	{
	}

	/**
	 * Funcio que escolta els events de quan la finestra s'obre.
	 * @param e Event rebut.
	 */
	public void windowOpened(WindowEvent e) 
	{
	}

}
